package com.game.manager.security;

import com.alibaba.fastjson.JSONObject;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Slf4j
@Configuration
@AllArgsConstructor
@EnableWebSecurity(debug = true)
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private ApplicationContext applicationContext;
    @PostConstruct
    public void init() {
        Object bean = applicationContext.getBean("springSecurityFilterChain");
        log.info("Bean 名字：{}", bean.getClass().getName());
    }
    @Override
    public void configure(WebSecurity webSecurity) {
        // 把静态资源和登陆页面忽略掉，不进行权限验证
        webSecurity.ignoring().antMatchers(HttpMethod.GET,
                "/",
                "/**",
                "/favicon.ico",
                "/gm/layout/index",
                "/layout/index",
                "/gm/user/login",
                "/user/login",
                "/gm/login",
                "/statics/**",
                "/statics/jquery.min.js",
                "/statics/easyui/**",
                "/statics/easyui/*.js",
                "/statics/layui/**",
                "/statics/layui/*.js",
                "/statics/server-option/**",
                "/statics/server-option/*.js",
                "/statics/images/*.jpg",
                "/jquery.min.js",
                "/easyui/**",
                "/easyui/*.js",
                "/layui/**",
                "/layui/*.js",
                "/server-option/**",
                "/server-option/*.js",
                "/images/*.jpg",
                "/templates/**",
                "/templates/*.html",
                "/templates/dev/*.html",
                "/templates/system/*.html",
                "/*.html",
                "/dev/*.html",
                "/system/*.html",
                "/**/*.html",
                "/**/*.css",
                "/**/*.js",
                "/**/*.jpg");
    }
    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity
                .formLogin()
                .loginPage("/gm/layout/index") // 设置登陆页面
                .loginProcessingUrl("/gm/account/login") // 设置处理登陆提交的path
                .and()
                .csrf().disable()
                .sessionManagement()//.disable()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .antMatchers("/gm/account/login","/gm/layout/**","/gm/user/**").permitAll()//"/gm/menu/**","/gm/gm-role/**",
                .antMatchers(HttpMethod.OPTIONS).permitAll()//跨域请求会先进行一次options请求
                .anyRequest().authenticated();

        // 替换过滤器
        AjaxJsonUsernamePasswordAuthenticationFilter ajaxJsonLoginFilter = new AjaxJsonUsernamePasswordAuthenticationFilter();
        ajaxJsonLoginFilter.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/gm/account/login", "POST"));
        // 配置认证类
        GmAuthenticationManager authenticationManager = new GmAuthenticationManager();
        ajaxJsonLoginFilter.setAuthenticationManager(authenticationManager);


        //处理认证成功之后的返回
        ajaxJsonLoginFilter.setAuthenticationSuccessHandler((request, response, authentication) -> {
            JSONObject data = new JSONObject();
            data.put("code", 0);
            data.put("msg", "登陆成功");
            this.response(response, data);
        });
        //处理认证失败之后的返回
        ajaxJsonLoginFilter.setAuthenticationFailureHandler((request, response, exception) -> {
            JSONObject data = new JSONObject();
            data.put("code", -1);
            data.put("msg", "登陆失败:" + exception.getMessage());
            this.response(response, data);
        });
        // 替换掉旧的登陆处理过滤器
        httpSecurity.addFilterBefore(ajaxJsonLoginFilter, UsernamePasswordAuthenticationFilter.class);
    }

    //返回数据
    private void response(HttpServletResponse response, JSONObject data) {
        String str = data.toJSONString();
        try {
            response.getOutputStream().write(str.getBytes("utf8"));
            response.getOutputStream().flush();
        } catch (IOException e) {
           log.error("数据返回错误",e);
        }
    }
}